package com.sunricher.telinkblemeshlib;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;

import java.util.HashMap;

public class LeScannerHelper {

    public static abstract class Callback {
        public abstract void leScannerUpdateDiscoveringState(String mac, boolean isDiscovering);
    }

    private BluetoothLeScanner bluetoothLeScanner;
    private boolean isScanning = false;
    private Callback callback;
    private HashMap<String, Boolean> discoveringMap = new HashMap<>();

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    protected LeScannerHelper() {

    }

    @SuppressLint("MissingPermission")
    protected void startLeScan(Context context) {
        if (isScanning) {
            return;
        }
        discoveringMap.clear();
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            return;
        }
        bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
        if (bluetoothLeScanner == null) {
            return;
        }
        isScanning = true;
        bluetoothLeScanner.startScan(leScanCallback);
    }

    @SuppressLint("MissingPermission")
    protected void stopLeScan() {
        isScanning = false;
        discoveringMap.clear();
        if (bluetoothLeScanner != null) {
            bluetoothLeScanner.stopScan(leScanCallback);
        }
    }

    private final ScanCallback leScanCallback =
            new ScanCallback() {
                @Override
                public void onScanResult(int callbackType, ScanResult result) {
                    String mac = result.getDevice().getAddress();
                    byte[] scanRecord = result.getScanRecord().getBytes();
                    if (mac != null && scanRecord.length > 20) {
                        Boolean current = discoveringMap.get(mac);
                        boolean isDiscovering = scanRecord[19] == 0x18 && scanRecord[20] == 0x03;
                        if (current != null && current == isDiscovering) {
                            return;
                        }
                        discoveringMap.put(mac, isDiscovering);
                        if (callback != null) {
                            callback.leScannerUpdateDiscoveringState(mac, isDiscovering);
                        }
                    }
                }
            };
}
